﻿/*  
 *  IIS LogFile Analyser, Copyright (C) 2013. http://www.iis-analyser.com
 *  --
 *  This program is free software, provided "AS IS" WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE
 * 
 *  File Author: Ian Quigley,    2013-02-23
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SQLite;

namespace DataStore
{
    [TableName("Account")]
    public class AccountRecord
    {
        [FieldDescription("Id", "long, PK")]
        public long Id { get; set; }
        public string Username { get; set;  }
        [FieldDescription("Email", "Login name, string")]
        public string Email { get; set;  }
        [FieldDescription("EncPassword", "Currently unencrypted password, string")]
        public string Password { get; set; }
        [FieldDescription("LoginAttempts", "Number of login attempts, long")]
        public long LoginAttempts { get; set; }
        
        internal static void InitialiseTable()
        {
            using (SQLiteConnection connection = new SQLiteConnection( Database.DataSource ))
            using (SQLiteCommand command = new SQLiteCommand( "CREATE TABLE if not exists Account (Id Integer PRIMARY KEY AutoIncrement, Username Text, Email text, EncPassword text, LoginAttempts long)", connection ))
            {
                connection.Open();
                command.ExecuteNonQuery();
                connection.Close();
            }
        }

        public void Save()
        {
            using (SQLiteConnection connection = new SQLiteConnection( Database.DataSource ))
            using (SQLiteCommand command = new SQLiteCommand( "INSERT OR REPLACE INTO Account (" + (Id == 0 ? "" : "Id, ") + "Username, Email, EncPassword, LoginAttempts) VALUES (" + (Id == 0 ? "" : "@Id, ") + "@username, @email, @encpassword, @loginAttempts); select last_insert_rowid();", connection ))
            {
                if (Id != 0)
                    command.Parameters.AddWithValue( "@Id", Id );

                command.Parameters.AddWithValue( "@username", Username);
                command.Parameters.AddWithValue( "@email", Email);
                command.Parameters.AddWithValue( "@encpassword", Password );
                command.Parameters.AddWithValue( "@loginattempts", LoginAttempts);

                connection.Open();
                Id = (long)command.ExecuteScalar();
                connection.Close();            
            }        
        }

        public static AccountRecord Login(string email, string password)
        {
            AccountRecord found = null;
            using (SQLiteConnection connection = new SQLiteConnection( Database.DataSource ))
            using (SQLiteCommand command = new SQLiteCommand( "SELECT * FROM Account WHERE Email = @email;", connection ))
            {
                command.Parameters.AddWithValue( "@email", email );
                connection.Open();
                var reader = command.ExecuteReader();
                if (reader.Read())
                    found = FromReader( reader );

                // Correct password and need to reset LoginAttempts to 0.
                if (found.Password == password && found.LoginAttempts != 0)
                {
                    found.LoginAttempts = 0;
                    found.Save();
                }

                // Too many invalid password attempts
                if (found.LoginAttempts > 50)
                    found = null;

                    
                connection.Close();
            }

            return found;
        }

        private static AccountRecord FromReader( SQLiteDataReader reader )
        {
            var account = new AccountRecord();
            account.Id = (long)reader["Id"];
            account.Username = (string)reader["Username"];
            account.Email = (string)reader["Email"];
            account.LoginAttempts = (long)reader["LoginAttempts"];

            return account;
        }

        internal static bool AnyDefined()
        {
            bool exists = false;

            using (SQLiteConnection connection = new SQLiteConnection(Database.DataSource))
            using (SQLiteCommand command = new SQLiteCommand("SELECT * FROM sqlite_master WHERE Name = 'Account' ", connection))
            {
                connection.Open();
                var reader = command.ExecuteReader();
                exists = reader.Read();
                connection.Close();
            }

            if (exists)
            {
                using (SQLiteConnection connection = new SQLiteConnection(Database.DataSource))
                using (SQLiteCommand command = new SQLiteCommand("SELECT Id FROM Account LIMIT 1", connection))
                {
                    connection.Open();
                    var reader = command.ExecuteReader();
                    exists = reader.Read();
                    connection.Close();
                }
            }
            return exists;
        }
    }
}
